package com.codeoss.framework.view.parser;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.ExpressionUtil;
import com.codeoss.framework.util.StringUtils;
import com.codeoss.framework.view.component.Component;
import com.codeoss.framework.view.component.Container;
import com.codeoss.framework.view.component.IDataBinding;
import com.codeoss.framework.view.component.Page;
import com.codeoss.framework.view.datasource.DataSourceConfig;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

@Service
public class PageParser extends AbstractComponentParser {
	protected void setAttributes(IParseContext parseContext, ObjectNode objectNode,Component component) {
		Page page=(Page)component;
		parseContext.setPage(page);;
		ObjectNode propertyMapNode=(ObjectNode)objectNode.get("propertyMap");
		if(propertyMapNode!=null) {
			JsonNode jsonNode=propertyMapNode.get("pageCode");
			if(jsonNode!=null) {
				String code=propertyMapNode.get("pageCode").asText();
				page.setCode(code);
			}
			
			jsonNode=propertyMapNode.get("title");
			if(jsonNode!=null) {
				String title=propertyMapNode.get("title").asText();
				page.setName(title);
			}
			
			jsonNode=propertyMapNode.get("pageBean");
			if(jsonNode!=null) {
				String pageBean=propertyMapNode.get("pageBean").asText();
				page.setPageBean(pageBean);
			}
			
			jsonNode=propertyMapNode.get("pageContext");
			if(jsonNode!=null) {
				String pageContext=jsonNode.asText();
				String pageContextArray[]=pageContext.split(",");
				for(int i=0;i<pageContextArray.length;i++) {
					String pageContextPair=pageContextArray[i];
					String pageContextPairArray[]=pageContextPair.split(":");
					page.addPageContext(pageContextPairArray[0], pageContextPairArray[1]);
				}
			}
		}
		JsonNode jsonNode=objectNode.get("dataSourceList");
		if(jsonNode!=null) {
			List<DataSourceConfig> dataSourceConfigList=new ArrayList<DataSourceConfig>();
			ArrayNode arrayNode=(ArrayNode)jsonNode;
			for(int i=0;i<arrayNode.size();i++) {
				ObjectNode dataSourceNode=(ObjectNode)arrayNode.get(i);
				DataSourceConfig dataSourceConfig=new DataSourceConfig();
				dataSourceConfigList.add(dataSourceConfig);
				dataSourceConfig.setId(dataSourceNode.get("id").asText());
				dataSourceConfig.setName(dataSourceNode.get("name").asText());
				
				JsonNode dataSourceJsonNode=dataSourceNode.get("tableName");
				if(dataSourceJsonNode!=null) {
					dataSourceConfig.setTableName(dataSourceNode.get("tableName").asText());
				}
				dataSourceJsonNode=dataSourceNode.get("whereClause");
				if(dataSourceJsonNode!=null) {
					String whereClause=dataSourceJsonNode.asText();
					if(!StringUtils.isEmpty(whereClause)) {
						Expression expression = new Expression();
						expression.setScriptType(Expression.EXPRESSION_TYPE_JAVASCRIPT);
						expression.setScript(whereClause);
						dataSourceConfig.setWhereClause(expression);
					}
				}
				dataSourceJsonNode=dataSourceNode.get("query");
				if(dataSourceJsonNode!=null) {
					String query=dataSourceJsonNode.asText();
					Expression expression=ExpressionUtil.convertToExpression(query, Expression.EXPRESSION_TYPE_JAVASCRIPT);
					dataSourceConfig.setQuery(expression);
				}
				dataSourceJsonNode=dataSourceNode.get("orderBy");
				if(dataSourceJsonNode!=null) {
					String orderBy=dataSourceJsonNode.asText();
					if(!StringUtils.isEmpty(orderBy) && !orderBy.equals("null")) {
						dataSourceConfig.setOrderBy(orderBy);
					}
				}
			}
			page.setDataSourceConfigList(dataSourceConfigList);
		}
		super.setAttributes(parseContext, objectNode, component);
	}
	
	 public void afterPageParse(IParseContext parseContext,Component component) {
    	Page page=(Page)component;
    	List<IDataBinding> dataBindingList=new ArrayList<IDataBinding>();
    	getAllComponent(page,dataBindingList);
    	page.setAttribute("_dataBindingList_", dataBindingList);
    	super.afterPageParse(parseContext, component);
	}

    protected void getAllComponent(Component component,List<IDataBinding> dataBindingList) {
    	if(component instanceof IDataBinding) {
    		dataBindingList.add((IDataBinding)component);
    	}
    	if(component instanceof Container) {
    		Container c=(Container)component;
    		for(int i=0;i<c.getChildren().size();i++) {
    			getAllComponent(c.getChildren().get(i),dataBindingList);
    		}
    	}
    }
    
	@Override
	protected Component createComponent(IParseContext parseContext, ObjectNode objectNode) {
		// TODO Auto-generated method stub
		return new Page();
	}

}
